//
// Created by wty on 22-7-4.
//
#include"sylar/sylar.h"
#include"sylar/iomanager.h"
#include<sys/types.h>
#include<sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include"sylar/timer.h"
#include<chrono>
#include"sylar/threadpool.h"

sylar::Logger::ptr logger = SYLAR_LOG_ROOT();

int sock = 0;

void test_fiber(){
    
    SYLAR_LOG_INFO(logger)<< "test fiber sock= "<<sock;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    fcntl(sock, F_SETFL, O_NONBLOCK);

    sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(6666);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    if (!connect(sock, (struct sockaddr*)&addr, sizeof(addr))) {

    }else if(errno == EINPROGRESS) {
        SYLAR_LOG_INFO(logger) << "add event errno=" << errno << " " << strerror(errno);

        sylar::IOManager::GetThis()->addEvent(sock, sylar::IOManager::READ, [](){
            SYLAR_LOG_INFO(logger) << "read callback";
        });

        sylar::IOManager::GetThis()->addEvent(sock, sylar::IOManager::WRITE, [](){
            SYLAR_LOG_INFO(logger) << "write callback";
            //close(sock);
            sylar::IOManager::GetThis()->cancelEvent(sock, sylar::IOManager::READ);
            close(sock);
        });
    } else {
        SYLAR_LOG_INFO(logger) << "else " << errno << " " << strerror(errno);
    }

}

void test1(){
    sylar::IOManager iom;
    iom.schedule(&test_fiber);
}

void test_set(){
    std::set<int> myset;
    std::set<int>::iterator itlow,itup;

    for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90

    itlow=myset.lower_bound (30);                //       ^
    itup=myset.upper_bound (60);                 //                   ^

    myset.erase(itlow,itup);                     // 10 20 70 80 90

//    std::cout << "myset contains:";
//    for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
//        std::cout << ' ' << *it;
//    std::cout << '\n';

}

void test_timer(){
    sylar::Timer::ptr timer;
    sylar::IOManager iom(2, true, "test_timer");
    timer = iom.addTimer(500, [&timer](){
        static int i = 0;
        if(i++==5){
            timer->reset(2000, true);
//            timer->cancel();
        }
        SYLAR_LOG_INFO(logger) << " recurring timer "<< " i="<<i;
    }, true);
}

void test_iomanager_performance(){
    sylar::IOManager iom(1);
    for(int i=0; i<100000; i++){
        iom.schedule(test_set);
    }
};

void test_thread(){
    ThreadPool thrpool(1);
    for(int i=0;i<100000; i++){
        thrpool.commit(test_set);
    }
}

int main(int argc, char** argv){

    //    test1();
    //test_timer();

    auto start = std::chrono::system_clock::now();
    test_thread();
    auto end = std::chrono::system_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << " thread durations: " <<  duration.count() <<"ms"<<std::endl;

    start = std::chrono::system_clock::now();
    test_iomanager_performance();
    end = std::chrono::system_clock::now();
    duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << " fiber durations: " <<  duration.count() <<"ms"<<std::endl;
    return 0;
}